#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#define DEFAULT_PORT	5019
HANDLE t[2];
//boolean flag[2];
//int turn;
int mutex = 1;
char	server_name[100];
FILE *des;
void wait(int mutext);
void signal(int mutex);

void wait(int mutex)
{
	while (mutex <= 0);
	mutex--;
}

void signal(int mutex)
{
	mutex++;
}

void Send(SOCKET serverSocket)
{
	char szBUFF[1000];
	int SEND;
	while (1)
	{
		//WaitForSingleObject(hMutex, INFINITE);
		gets_s(szBUFF, 100);		
		SEND = send(serverSocket, szBUFF, sizeof(szBUFF), 0);
		wait(mutex);
		des=fopen("client.txt", "a+");
		fprintf(des, "Send to %s: %s\n", server_name, szBUFF);
		fclose(des);
		signal(mutex);
		if (SEND <= 0)
		{
			break;
		}	
		else if (SEND>0&&strcmp(szBUFF, "Bye") == 0)
		{
			break;
		}
		Sleep(1000);
		//ReleaseMutex(hMutex);
	}
	closesocket(serverSocket);
	return;
}

void Rec(SOCKET serverSocket)
{
	char rec[1000];
	int Receive;
	while (1)
	{
		//WaitForSingleObject(hMutex, INFINITE);
		Receive = recv(serverSocket, rec, sizeof(rec) , 0);
		if (Receive <= 0)
		{
			break;
		}
		printf("%s\n", rec);
		wait(mutex);
		des=fopen("client.txt", "a+");
		fprintf(des, "Receive from %s: %s\n", server_name,rec);
		fclose(des);
		signal(mutex);
		Sleep(1000);
		//ReleaseMutex(hMutex);
	}
	closesocket(serverSocket);
}

int main(int argc, char **argv){

	char szBuff[100];
	//int msg_len;
	//int addr_len;
	struct sockaddr_in server_addr;
	struct hostent *hp;
	SOCKET connect_sock;
	WSADATA wsaData;

	
	unsigned short	port = DEFAULT_PORT;
	unsigned int	addr;

	/*if (argc != 3){
		printf("echoscln [server name] [port number]\n");
		return -1;
	}
	else{
		server_name = argv[1];
		port = atoi(argv[2]);
	}*/

	printf("Who do you want to connect: ");
	gets_s(server_name, 100);

	if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){
		// stderr: standard error are printed to the screen.
		fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
		//WSACleanup function terminates use of the Windows Sockets DLL. 
		WSACleanup();
		return -1;
	}

	printf("The Server IP Address: %s",server_name);

	if (isalpha(server_name[0]))
		hp = gethostbyname(server_name);
	else{
		addr = inet_addr(server_name);
		hp = gethostbyaddr((char*)&addr, 4, AF_INET);
	}

	if (hp == NULL)
	{
		fprintf(stderr, "Cannot resolve address: %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//copy the resolved information into the sockaddr_in structure
	memset(&server_addr, 0, sizeof(server_addr));
	memcpy(&(server_addr.sin_addr), hp->h_addr, hp->h_length);
	server_addr.sin_family = hp->h_addrtype;
	server_addr.sin_port = htons(port);


	connect_sock = socket(AF_INET, SOCK_STREAM, 0);	//TCp socket


	if (connect_sock == INVALID_SOCKET){
		fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	printf("Client connecting to: %s\n", hp->h_name);

	if (connect(connect_sock, (struct sockaddr *)&server_addr, sizeof(server_addr))== SOCKET_ERROR)
	{
		fprintf(stderr, "connect() failed with error %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
	//while (1)
	//{
		for (int i = 0; i < 2; i++)
		{
			if (i == 0)
			{
				t[i]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Send, (LPVOID)connect_sock, 0, 0);
			}
			else
			{
				t[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Rec, (LPVOID)connect_sock, 0, 0);
			}
		}
		for (int i = 0; i < 2; i++)
		{
			WaitForSingleObject(t[i], INFINITE);
			CloseHandle(t[i]);
		}		
		Sleep(1000);
	//}
	printf("Echo from the server %s.\n", szBuff);
	//getchar();
	WSACleanup();
	return -1;
}

